
import { BUNDLE_TYPE_ENUM, EVENT_NAME_ENUM } from "./base/EnumIndex";
import { TOUCH_MOVE_LEN } from "./base/GameIndex";
import { ActionTools } from "./common/ActionTools";
import { Tools } from "./common/Tools";
import { AudioManager1 } from "./manager/AudioManager1";
import { EventManager } from "./manager/EventManager";
import { LevelManager } from "./manager/LevelManager";
import { ResManager1 } from "./manager/ResManager1";
import { UIManager } from "./manager/UIManager";
import { InterInfo, InitInfo, TweenInfo, AudioInfo } from "./model/OtherModel";
import LevelBase from "./LevelBase";

const { ccclass, property } = cc._decorator;

@ccclass
export default class LvItem extends cc.Component {
    // initInfo: InitInfo = null;   //初始化的配置信息   暂时用不到
    // interInfo: InterInfo = null;   //交互的配置信息
    interInfoArr: Array<InterInfo> = [];   //交互的配置信息

    levelBase: LevelBase = null;   //关卡总类

    initPos: cc.Vec3 = null;   //初始化的时候的坐标
    initSibIndex: number = 0;    //初始化时候得层级
    isClick: boolean = true;  //是否可点击自身

    touchTime: number = 0;    //按下屏幕的时间
    isTouchMove: boolean = false;   //是否按住节点移动过
    isTouchStart: boolean = false;    //是否开始按下屏幕
    touchStartPos: cc.Vec3 = null;   //触摸开始坐标
    clickNum: number = 0;        //当前点击次数;
    maxClickNum: number = 0;     //点击多少次后触发
    cuoTime: number = 0;         //按住拖动的时间
    countRunTween: number = 0         //计数执行Tween   

    onLoad() {
        this.initPos = cc.v3(this.node.position);
        this.initSibIndex = this.node.getSiblingIndex();
    }
    protected onDestroy(): void {
        this.unscheduleAllCallbacks();
        this.node.off(cc.Node.EventType.TOUCH_START, this.touchStartBack, this);
        this.node.off(cc.Node.EventType.TOUCH_MOVE, this.touchMoveBack, this);
        this.node.off(cc.Node.EventType.TOUCH_END, this.touchMoveEndBack, this);
        this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.touchMoveEndBack, this);
    }
    update(dt: number) {
        this.updateTouchTime(dt);
    }
    /** 初始化本物品 */
    initItem(levelBase: LevelBase) {
        this.levelBase = levelBase;
    };
    /** 根据配置 初始化物品的信息 */
    initItemInfo(initInfo: InitInfo) {
        this.scheduleOnce(() => {
            if (initInfo.initPos) {
                this.node.position = cc.v3(initInfo.initPos.x, initInfo.initPos.y);
            }
            this.initItemAni(initInfo);
        }, 0);
    };
    /** 播放初始化时动画 */
    initItemAni(tweenInfo: InitInfo) {
        if (tweenInfo.interTween) {
            this.runTweenInfo(tweenInfo.interTween)
        }
    };
    /** 初始化交互配置 */
    initInterItem(interInfo: InterInfo) {
        this.interInfoArr.push(interInfo);
        // this.interInfo = interInfo;

        this.node.on(cc.Node.EventType.TOUCH_START, this.touchStartBack, this);

        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMoveBack, this);
        // if (this.getInterForType("touchMove", true)) {  /** 拖动 */
        //     this.node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMoveBack, this);
        // }
        this.node.on(cc.Node.EventType.TOUCH_END, this.touchMoveEndBack, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.touchMoveEndBack, this);
    };
    /** 触摸开始回调 */
    touchStartBack(touch: cc.Event.EventTouch) {
        if (!this.isClick) { return; }
        this.isTouchMove = false;
        this.isTouchStart = true;
        this.touchStartPos = cc.v3(touch.getLocation());

        if (this.getInterForType("touchStart")) {
            this.runNodeInter(this.getInterForType("touchStart"));
        }
    };
    /** 触摸移动回调 */
    touchMoveBack(touches: cc.Event.EventTouch) {
        if (!this.touchStartPos) {
            this.touchStartPos = cc.v3(touches.getLocation());
        }
        if (!this.isClick || Tools.getDistance(this.touchStartPos, touches.getLocation()) <= TOUCH_MOVE_LEN) { return; }
        this.isTouchMove = true;
        let moveScale = this.getWorldScale(1, this.node);
        // cc.log(this.getWorldScale(this.node.scale,this.node),moveScale)


        let cuoInfo = this.getInterForType("touchCuoTime")
        if (cuoInfo) {
            this.cuoTime += 0.02;
            if (this.cuoTime > cuoInfo.interValue) {
                this.cuoTime = 0;
                return this.runNodeInter(cuoInfo);
            }
        } if (this.getInterForType("touchMoveLeft", true) && touches.getDelta().x < 0) {
            this.node.position = this.node.position.add(cc.v3(touches.getDelta().x * moveScale, 0));

            let moveLenInfo = this.getInterForType("touchMoveLeftLen");
            if (moveLenInfo && Math.abs(this.touchStartPos.x - touches.getLocation().x) >= moveLenInfo.interValue) {
                this.runNodeInter(moveLenInfo);
            }
        }
        if (this.getInterForType("touchMoveRight", true) && touches.getDelta().x > 0) {
            this.node.position = this.node.position.add(cc.v3(touches.getDelta().x * moveScale, 0));

            let moveLenInfo = this.getInterForType("touchMoveRightLen");
            if (moveLenInfo && Math.abs(this.touchStartPos.x - touches.getLocation().x) >= moveLenInfo.interValue) {
                this.runNodeInter(moveLenInfo);
            }
        }
        if (this.getInterForType("touchMoveTop", true) && touches.getDelta().y > 0) {
            this.node.position = this.node.position.add(cc.v3(0, touches.getDelta().y * moveScale));

            let moveLenInfo = this.getInterForType("touchMoveTopLen");
            if (moveLenInfo && Math.abs(this.touchStartPos.y - touches.getLocation().y) >= moveLenInfo.interValue) {
                this.runNodeInter(moveLenInfo);
            }
        }
        if (this.getInterForType("touchMoveDown", true) && touches.getDelta().y < 0) {
            this.node.position = this.node.position.add(cc.v3(0, touches.getDelta().y * moveScale));

            let moveLenInfo = this.getInterForType("touchMoveDownLen");
            if (moveLenInfo && Math.abs(this.touchStartPos.y - touches.getLocation().y) >= moveLenInfo.interValue) {
                this.runNodeInter(moveLenInfo);
            }
        }
        if (this.getInterForType("touchMove") || this.getInterForType("touchMove_Click") || this.getInterForType("touchMoveLen")
            || this.getInterForType("touchMoveLenNode")) {
            this.node.position = this.node.position.add(cc.v3(touches.getDelta().multiplyScalar(moveScale)));

            let moveLenInfo = this.getInterForType("touchMoveLen");
            if (moveLenInfo && Tools.getDistance(this.touchStartPos, touches.getLocation()) >= moveLenInfo.interValue) {
                this.runNodeInter(moveLenInfo);
            }
            let moveLenInfo2 = this.getInterForType("touchMoveLenNode");
            if (moveLenInfo2 && Tools.getDistance(this.initPos, this.node.position) >= moveLenInfo2.interValue) {
                this.runNodeInter(moveLenInfo2);
            }
        }
    };
    /** 触摸移动结束回调 */
    touchMoveEndBack(touches: cc.Event.EventTouch) {
        if (!this.isClick || !this.isTouchStart) { return; }
        this.isTouchStart = false;
        this.touchTime = 0;
        this.cuoTime = 0;

        let endInfo = this.getInterForType("touchEnd");
        if (endInfo) {
            this.runNodeInter(endInfo);
        }
        if (this.isTouchMove) {
            let moveInfo = this.getInterForType("touchMove") || this.getInterForType("touchMove_Click");
            if (moveInfo && moveInfo.interNode) {
                let interNodes = null;
                if (typeof moveInfo.interNode == "string") {
                    interNodes = [moveInfo.interNode]
                } else {
                    interNodes = moveInfo.interNode;
                }
                for (let i = 0; i < interNodes.length; i++) {
                    let node2 = this.levelBase.getNodeForName(interNodes[i]);
                    if (this.isNodeInterNode(node2, this.node)) {
                        this.runNodeInter(moveInfo);
                        return;
                    }
                }
                cc.tween(this.node).to(0.2, { position: this.initPos }).start();
            }
        } else {
            if (this.getInterForType("touchMove_Click")) {
                this.levelBase.runNodeTween(this.node, this.levelBase.getInterTwForName(this.node.name + "_click").interTween);
            } else {
                this.clickCallBack();
            }
            // if (this.node.getBoundingBoxToWorld().contains(touches.getLocation())) {
            // }
        }
    };
    clickTween: cc.Tween = null;   //连击Tween
    /** 点击事件 */
    clickCallBack() {
        let clickNumInfo = this.getInterForType("clickNum");
        let clickInfo = this.getInterForType("click");
        this.clickNum++;
        if (clickNumInfo) {
            if (this.clickTween) {
                this.clickTween.stop();
            }
            if (this.clickNum == clickNumInfo.interValue) {
                this.runNodeInter(clickNumInfo);
            } else {
                this.clickTween = cc.tween(this.node).delay(0.2).call(() => {
                    this.clickTween = null;
                    this.clickNum = 0;
                    if (clickInfo) {
                        this.runNodeInter(clickInfo);
                    }
                }).start();
            }
            return;
        }
        let maxInfo = this.getInterForType("maxClickNum");
        if (maxInfo) {
            this.maxClickNum++;
            if (this.maxClickNum == maxInfo.interValue) {
                this.runNodeInter(maxInfo);
                return;
            }
        }
        this.clickNum = 0;
        if (clickInfo) {
            this.runNodeInter(clickInfo);
        }
    };
    /** 是否含有该触发事件类型  并返回interInfo  isIncludes 是否包含字符串 */
    getInterForType(type?: string, isIncludes: boolean = false) {
        if (!type && this.interInfoArr.length > 0) {
            return this.interInfoArr[0];
        }
        for (let i = 0; i < this.interInfoArr.length; i++) {
            if (this.interInfoArr[i].interType == type || (isIncludes && this.interInfoArr[i].interType.includes(type))) {
                return this.interInfoArr[i];
            }
        }
        return null;
    };
    /** 获取正在播放的龙骨动画 */
    getArmtureAni() {
        let armature = this.node.getComponentInChildren(dragonBones.ArmatureDisplay);
        if (!armature) {
            armature = this.node.getComponent(dragonBones.ArmatureDisplay);
        }
        return armature.animationName;
    };
    /** 获取龙骨动画组件 */
    get armatureCom() {
        let armature = this.node.getComponentInChildren(dragonBones.ArmatureDisplay);
        if (!armature) {
            armature = this.node.getComponent(dragonBones.ArmatureDisplay);
        }
        return armature;
    };
    /** 获取本节点的spine组件 */
    get spineCom() {
        let spine = this.node.getComponent(sp.Skeleton);
        if (!spine) {
            spine = this.node.getComponentInChildren(sp.Skeleton);
        }
        return spine;
    };
    /** 刷新按下屏幕的时间 */
    updateTouchTime(dt: number) {
        if (!this.isClick) {
            this.touchTime = 0;
            return;
        }
        let longInfo = this.getInterForType("longTouch");
        if (longInfo && this.isTouchStart) {
            this.touchTime += dt;
            if (this.touchTime >= longInfo.interValue) {
                this.runNodeInter(longInfo);
                this.isTouchStart = false;
                this.touchTime = 0;
            }
        }
    };
    /** 执行本节点事件 */
    runNodeInter(interInfo?: InterInfo) {
        interInfo = interInfo || this.interInfoArr[0];
        UIManager.ins.enabledGameClick(interInfo.isAllClick);
        // EventManager.ins.emit(EVENT_NAME_ENUM.INTER_EVENT);
        this.runTweenInfo(interInfo.interTween);
    };
    /** 
     * 根据配置信息  播放Tween
     * runIndex  播放到哪个下标了
     * repeat    当前循环次数
     */
    runTweenInfo(tweenInfos: Array<TweenInfo>, runIndex: number = 0, repeat: number = 0) {
        if (runIndex > tweenInfos.length - 1) {
            return;
        }

        let info = tweenInfos[runIndex];
        let tw = this.getTweenForInfo(info);
        // cc.log("runTweenInfo", this.node.name, info)

        runIndex++;
        if (info.type == "repeat") {  //循环次数
            if (info.value == -1) {
                runIndex = 0;
            } else if (info.value > 1) {
                repeat++;
                if (repeat == info.value) { return; }
                runIndex = 0;
            }
            tw = cc.tween(this.node);
        }

        tw.call(() => {
            this.runTweenInfo(tweenInfos, runIndex, repeat);
        }, this).start();
    };
    /** 根据配置获取Tween */
    getTweenForInfo(info: TweenInfo) {
        let tw = new cc.Tween();
        tw.target(this.node);
        if (info.node && info.node != this.node.name) {  //执行其他节点动作
            // cc.log(info,this.node);
            EventManager.ins.emit(EVENT_NAME_ENUM.RUN_OTHER_TWEEN, info);
            return tw;
        }

        // 执行自身节点动作
        if (info.type == "delay") {   //等待几秒
            tw = tw.delay(info.value)
        } else if (info.type.includes("By") || info.type.includes("To")) {  //缓动属性的Tween
            tw = this.getNodeTween(info);
        } else if (info.type.includes("set") || info.type == "active") {//直接设置某个属性
            this.getSetNodeTween(info);
        } else if (info.type.includes("Ani")) {
            this.getOtherAniTween(info);
        } else {
            this.getOtherCallTween(info);
        }
        return tw;
    };
    /** 展示对话框 */
    async showTalk(data: TweenInfo, showType: number = 1, scale = 1) {
        if (!AudioManager1.isSubtitle) { return; }
        if (data.pos) {
            this.node.getChildByName("talkPos").position = cc.v3(data.pos.x, data.pos.y);
        }
        let pos = Tools.getToNodePosForNode(this.node.getChildByName("talkPos"), this.node.parent);
        let prefab = await ResManager1.ins.loadRes("prefab/node/talkNode_" + showType, cc.Prefab, BUNDLE_TYPE_ENUM.GAME);
        let talkNode = Tools.newPrefab(prefab, this.node.parent, cc.v2(pos.x, pos.y));

        talkNode.scale = 0;
        let lab = talkNode.getComponentInChildren(cc.Label);
        lab.string = "";

        if (data.timeScale) {
            talkNode.angle = data.timeScale;
        }
        cc.tween(talkNode)
            .to(0.2, { scaleX: scale, scaleY: scale }, { easing: cc.easing.backOut })
            .call(() => {
                ActionTools._ins.doLabStrAni(lab, data.value, data.time - 1.5)
            }).delay(data.time - 0.2)
            .to(0.2, { scale: 0 }, { easing: cc.easing.backIn })
            .call((target: cc.Node) => {
                target.destroy();
            }).start();
    };
    /** 播放龙骨动画 */
    playArmtureAni(armatureName: string, playTimes: number = -1, timeScale?: number) {
        let armature = this.node.getComponentInChildren(dragonBones.ArmatureDisplay);
        if (!armature) {
            armature = this.node.getComponent(dragonBones.ArmatureDisplay);
        }
        if (!armature) {
            this.playSpineAni(armatureName, playTimes, timeScale);
            return;
        }
        if (playTimes) {
            armature.playAnimation(armatureName, playTimes);
        } else {
            armature.playAnimation(armatureName, -1);
        }
        if (timeScale !== undefined) {
            armature.timeScale = timeScale;
        } else {
            armature.timeScale = 1;
        }
    };
    /** 播放Spine动画 */
    playSpineAni(armatureName: string, playTimes: number = -1, timeScale?: number) {
        let spine = this.node.getComponentInChildren(sp.Skeleton);
        if (!spine) {
            spine = this.node.getComponent(sp.Skeleton);
        }
        spine.setAnimation(0, armatureName, playTimes == 1 ? false : true)
        this.setArmtureScale(playTimes, timeScale);
    };
    /** 设置骨骼的隐藏显示 */
    setBoneActive(boneName: string, isActive: boolean) {
        if (this.armatureCom) {
            let bone = this.armatureCom.armature().getBone(boneName);
            if (!bone) { return; }
            bone.visible = isActive;
        } else {
            let bone = this.spineCom.findBone(boneName);
            if (!bone) { return; }
            bone.active = isActive;
        }
    };
    /** 设置骨骼插槽隐藏显示 */
    setSlotActive(boneName: string, isActive: boolean) {
        if (this.armatureCom) {
            let bone = this.armatureCom.armature().getSlot(boneName);
            if (!bone) { return; }
            bone.visible = isActive;
        } else {
            let bone = this.spineCom.findSlot(boneName);
            if (!bone) {
                cc.log(boneName + "卡槽找不到");
                return;
            }
            bone.active = isActive;
        }
    };
    /** 
     * 更换spine动画皮肤
     * @param skinName 皮肤名字
     * 用法：{ "type": "setSpineSkin", "node": "nodeName", "value": "skinName" }
     */
    setSpineSkin(skinName: string) {
        let spine = this.node.getComponent(sp.Skeleton)
        if (!spine) {
            cc.log(skinName + "skeleton骨骼找不到");
            return
        }
        spine.setSkin(skinName);
    }
    /** 设置spine/龙骨 卡槽上图片切换
     * @param slotName 插槽名
     * @param attachmentName 插槽上的图片名
     * 用法：{"type": "setAttachment", "node": "man_spine", "value": {"slot": "head", "attachment": "headImg"}}
     * 用法：{"type": "setAttachment", "node": "man_ske", "value": {"slot": "head", "attachment": "headImg"}}
     */
    setAttachment(slotName: string, attachmentName: string) {
        if (this.armatureCom) {
            let factory = dragonBones.CCFactory.getInstance();
            let slot = this.armatureCom.armature().getSlot(slotName);
            if (!slot) {
                cc.log(slotName + "卡槽找不到");
                return;
            }
            let key = this.armatureCom.getArmatureKey()//骨架key
            let armatureName = this.armatureCom.armature().name//骨架名
            factory.replaceSlotDisplay(key, armatureName, slotName, attachmentName, slot);
        } else {
            let slot = this.spineCom.findSlot(slotName);
            if (!slot) {
                cc.log(slotName + "卡槽找不到");
                return;
            }
            this.spineCom.setAttachment(slotName, attachmentName);
        }
    }
    /** 设置龙骨或者spine播放速率 */
    setArmtureScale(playTimes: number = -1, timeScale?: number) {
        if (this.armatureCom) {
            this.armatureCom.playTimes = playTimes;
            this.armatureCom.timeScale = timeScale;
        } else {
            let spine = this.spineCom;
            if (playTimes && playTimes > 1) {
                let playNumCall = (sp: sp.Skeleton, playTimes: number) => {
                    let num = 0;
                    sp.setCompleteListener(() => {
                        num++;
                        if (num >= playTimes) {
                            sp.timeScale = 0;
                            sp.loop = false;
                        }
                    });
                }
                playNumCall(spine, playTimes);
            }
            if (timeScale !== undefined) {
                spine.timeScale = timeScale;
            } else {
                spine.timeScale = 1;
            }
        }
    };
    /** aimation动画 */
    playAnimation(armatureName: string, startTime?: number) {
        let animation = this.node.getComponent(cc.Animation);
        if (!animation) {
            animation = this.node.getComponentInChildren(cc.Animation);
        }
        if (startTime == -1 && animation.currentClip) {
            startTime = animation.getAnimationState(animation.currentClip.name).time;
        }
        animation.play(armatureName, startTime);
    };
    /** aimation动画修改Speed速度 */
    playSD(armatureName: string, speed1: number, timeCS?: number) {
        let animation = this.node.getComponent(cc.Animation);
        if (!animation) {
            animation = this.node.getComponentInChildren(cc.Animation);
        }
        if (timeCS == -1 && animation.currentClip) {
            timeCS = animation.getAnimationState(animation.currentClip.name).time;
        }

        let PASD = animation.play(armatureName);
        animation.play(armatureName, timeCS);
        PASD.speed = speed1;
    };

    /** aimation动画 */
    stopAnimation(armatureName: string) {
        let animation = this.node.getComponent(cc.Animation);
        if (!animation) {
            animation = this.node.getComponentInChildren(cc.Animation);
        }
        animation.stop(armatureName);
    };
    /** 暫停aimation动画 */
    pauseAnimation(armatureName: string) {
        let animation = this.node.getComponent(cc.Animation);
        if (!animation) {
            animation = this.node.getComponentInChildren(cc.Animation);
        }
        animation.pause(armatureName);
    };
    /** 恢復aimation动画 */
    resumeAnimation(armatureName: string) {
        let animation = this.node.getComponent(cc.Animation);
        if (!animation) {
            animation = this.node.getComponentInChildren(cc.Animation);
        }
        animation.resume(armatureName);
    };
    /** 声音音量 变化Tween */
    setAudioValueAni(info: TweenInfo) {
        let audioID = AudioManager1.audioDic.get(info.value.resUrl);
        if (audioID === undefined) {
            return cc.log("未找到音效:", info.value.resUrl);
        }
        ActionTools._ins.audioValueTween(audioID, info.value.value, info.time)
            .target(this.node).start();
    };
    /** 修改Lab上的文字 */
    setLabString(labString: string) {
        let lab = this.node.getComponent(cc.Label);
        if (!lab) {
            lab = this.node.getComponentInChildren(cc.Label);
        }
        lab.string = labString;
    };
    /** 逐个字符出现 */
    doLabStringAni(info: TweenInfo) {
        let lab = this.node.getComponentInChildren(cc.Label);
        if (!lab) {
            lab = this.node.getComponent(cc.Label);
        }
        ActionTools._ins.doLabStrAni(lab, info.value, info.time);
    };
    /** 滚动字符出现 */
    gunLabStringAni(info: TweenInfo) {
        let lab = this.node.getComponentInChildren(cc.Label);
        if (!lab) {
            lab = this.node.getComponent(cc.Label);
        }
        ActionTools._ins.gunNumLabAni(lab, info.value);
    };
    /** 播放摇晃动画 */
    playShakeAni(time: number, value: any) {
        if (value.repeat == -1) {
            ActionTools._ins.shakeAni(this.node, true, value.angle, time, value.deT);
        } else {
            ActionTools._ins.shakeAni(this.node, false, value.angle, time, value.deT);
        }
    };
    /** 
     * 播放闪光灯动画
     * @参数 time 延迟几秒开始播放，默认1秒
     * @用法 { "type": "playKuaimenAni", "time": "1"} time不写默认1s
     * @注意 尽可能用于winGame或winGameAni里，或者node层级不能太深
     */
    async playKuaimenAni(time: number = 1) {
        let prefab = await ResManager1.ins.loadRes("prefab/node/快门动画", cc.Prefab, BUNDLE_TYPE_ENUM.GAME)
        let maskNode = this.node.getChildByName('maskNode').getChildByName('huaPre')
        let kuaimen = Tools.newPrefab(prefab, maskNode)

        this.scheduleOnce(async () => {
            await AudioManager1.playAudio("快门声", 1, BUNDLE_TYPE_ENUM.GAME);
            kuaimen.active = true
            this.scheduleOnce(() => {
                kuaimen.active = false
            }, 0.5)
        }, time)
    }
    /** 播放音效 */
    async playAudio(audioInfo: AudioInfo) {
        let bundleType = BUNDLE_TYPE_ENUM.LEVEL;
        let uiAudioArr = ["xuandui"];
        let idx = uiAudioArr.findIndex(i => i === audioInfo.resUrl);
        if (idx >= 0) bundleType = BUNDLE_TYPE_ENUM.GAME;
        let audioId: any = await AudioManager1.playAudio(audioInfo.resUrl, audioInfo.value, bundleType);
        AudioManager1.setAudioLoop(audioId, audioInfo.isRepeat);

        if (audioInfo.bgmValue || audioInfo.bgmValue === 0) {
            /** 设置背景音乐音量 */
            AudioManager1.setBgValue(audioInfo.bgmValue);
        }
    };
    /** 停止动作 */
    stopTween(stopVa: string) {
        if (stopVa == "stop") {
            cc.Tween.stopAllByTarget(this.node);
        } else if (stopVa == "pause") {
            this.node.pauseAllActions();
        } else if (stopVa == "resume") {
            this.node.resumeAllActions();
        }
    };
    /** 设置坐标 */
    setPosForInfo(value: any) {
        //增加能直接设置坐标为初始坐标
        if (value == "initPos") {
            return this.node.position = this.initPos;
        }
        if (typeof value == "string") {
            this.node.position = cc.v3(Tools.getToNodePosForNode(this.levelBase.getNodeForName(value), this.node.parent));
            // this.node.position = this.levelBase.getNodeForName(value).position;
        } else {
            if (Math.abs(value.x) < 1) {
                value.x = cc.winSize.width * value.x;
            } if (Math.abs(value.y) < 1) {
                value.y = cc.winSize.height * value.y;
            }
            this.node.position = cc.v3(value.x, value.y)
        }
    };
    /** 移动至某个位置 */
    getMoveToTw(info: TweenInfo) {
        if (info.value == "initPos") {
            return cc.tween(this.node).to(info.time, { position: this.initPos }, { easing: info.value.easing || "smooth" });
        }
        if (typeof info.value == "string") {
            let toPos = Tools.getToNodePosForNode(this.levelBase.getNodeForName(info.value), this.node.parent);
            return cc.tween(this.node).to(info.time, { position: cc.v3(toPos) });
        }
        return cc.tween(this.node).to(info.time, { position: cc.v3(info.value.x, info.value.y) }, { easing: info.value.easing || "smooth" });
    };
    /** 通过配置信息  获取贝塞尔曲线的三个点 */
    getBezierPos(infoValue: any) {
        return [cc.v2(infoValue[0].x, infoValue[0].y), cc.v2(infoValue[1].x, infoValue[1].y), cc.v2(infoValue[2].x, infoValue[2].y)]
    };
    /**
     * @Fun  计数执行一个Tween
     * @param Counttime 每次累加值
     * @param CountScale 峰值   累加到峰值 执行 NodeTween2
     * @usage {"type":"CountEn","node":"viewBg","value":"刮胡刀消失","time":1,"timeScale":2}
     */
    CountEnFun(initTween: string, NodeTween2: string, Counttime: number, CountScale: number) {
        this.countRunTween += Counttime;
        cc.log("计数节点《" + this.node.name + "》：当前计数" + this.countRunTween + "  峰值：" + CountScale);
        if (this.countRunTween == CountScale) {
            EventManager.ins.emit(EVENT_NAME_ENUM.RUN_NODE_TWEEN, initTween, NodeTween2);
        }
    }

    /** 根据配置获取一个修改节点属性的Tween */
    getNodeTween(info: TweenInfo) {
        switch (info.type) {
            case "moveBy":
                return cc.tween(this.node).by(info.time, { position: cc.v3(info.value.x, info.value.y) }, { easing: info.value.easing || "smooth" });
            case "moveTo":
                return this.getMoveToTw(info);
            case "rotateTo":
                return cc.tween(this.node).to(info.time, { angle: info.value }, { easing: info.value.easing || "smooth" });
            case "rotateBy":
                return cc.tween(this.node).by(info.time, { angle: info.value }, { easing: info.value.easing || "smooth" });
            case "jumpBy":
                let jumpBy = cc.jumpBy(info.time, cc.v2(info.value.x, info.value.y), info.value.height, info.value.jumps || 1)
                return cc.tween(this.node).then(jumpBy);
            case "jumpTo":
                let jumpTo = cc.jumpTo(info.time, cc.v2(info.value.x, info.value.y), info.value.height, info.value.jumps)
                return cc.tween(this.node).then(jumpTo);
            case "fadeTo":
                return cc.tween(this.node).to(info.time, { opacity: info.value });
            case "scaleTo":
                return cc.tween(this.node).to(info.time, { scaleX: info.value.x, scaleY: info.value.y }, { easing: info.value.easing || "smooth" });
            case "scaleBy":
                return cc.tween(this.node).by(info.time, { scaleX: info.value.x, scaleY: info.value.y }, { easing: info.value.easing || "smooth" });
            case "bezierBy":
                return cc.tween(this.node).then(cc.bezierBy(info.time, this.getBezierPos(info.value)));
            case "bezierTo":
                return cc.tween(this.node).then(cc.bezierTo(info.time, this.getBezierPos(info.value)));
            case "sizeBy":
                return cc.tween(this.node).by(info.time, { width: info.value.width, height: info.value.height }, { easing: info.value.easing || "smooth" });
            case "sizeTo":
                return cc.tween(this.node).to(info.time, { width: info.value.width, height: info.value.height }, { easing: info.value.easing || "smooth" });
        }
        return null;
    };
    /** 获取一个播放其他动画的Tween */
    getOtherAniTween(info: TweenInfo) {
        switch (info.type) {
            case "armatureAni":
                return this.playArmtureAni(info.value, info.time, info.timeScale);
            case "shakeAni":
                return this.playShakeAni(info.time, info.value);
            case "playAnimation":
                return this.playAnimation(info.value, info.time);
            case "playSDAni":     /** aimation动画修改Speed速度    time值=速度    timeScale = 播放到第几秒*/
                return this.playSD(info.value, info.time, info.timeScale);
            case "stopAnimation":
                return this.stopAnimation(info.value);
            case "pauseAnimation":
                return this.pauseAnimation(info.value);
            case "resumeAnimation":
                return this.resumeAnimation(info.value);
            case "audioValueAni":
                return this.setAudioValueAni(info);
            case "doLabStrAni":
                return this.doLabStringAni(info);
            case "gunLabStrAni":
                return this.gunLabStringAni(info);
            case "playKuaimenAni":
                return this.playKuaimenAni(info.time);
        }
        return null;
    };
    /** 获取一个直接设置节点属性的Tween */
    getSetNodeTween(info: TweenInfo) {
        switch (info.type) {
            case "setPos":
                return this.setPosForInfo(info.value);
            case "setOpa":
                return this.node.opacity = info.value;
            case "setScale":
                this.node.scaleX = info.value.x;
                this.node.scaleY = info.value.y;
                return;
            case "setSize":
                this.node.width = info.value.w;
                this.node.height = info.value.h;
                return;
            case "setColor":  // 设置节点颜色Color属性
                this.node.color = new cc.Color().fromHEX(info.value);
                return;
            case "setAngle":
                return this.node.angle = info.value;
            case "setParent":   //设置父节点  不改变坐标
                return Tools.setNodeParent(this.node, this.levelBase.getNodeForName(info.value));
            case "setZIndex":
                return this.node.zIndex = info.value;
            case "setLabStr":
                return this.setLabString(info.value);
            case "active":
                return this.node.active = info.value;
            case "setBoneActive":   //设置 某个骨骼显示隐藏
                return this.setBoneActive(info.value.bone, info.value.active);
            case "setSlotActive":   //设置 某个骨骼显示隐藏     没用
                return this.setSlotActive(info.value.bone, info.value.active);
            case "setSpineSkin":
                return this.setSpineSkin(info.value)
            case "setSpineAttachment":   //根据卡槽名和图片名 设置图片切换
            case "setAttachment":   //根据卡槽名和图片名 设置图片切换
                return this.setAttachment(info.value.slot, info.value.attachment);
            case "setNodeSpr":   //设置节点 图片
                return this.setNodeSpr(info.value);
            case "setInitPos":   //重新设置 初始坐标
                return info.value ? this.initPos = cc.v3(info.value.x, info.value.y) : this.initPos = cc.v3(this.node.position);
            case "setClick":
                return this.isClick = info.value;
            case "setSibIndex":
                return this.node.setSiblingIndex(info.value);
            case "setAllClick":
                return UIManager.ins.enabledGameClick(info.value);
        }
        return null;
    };
    async setNodeSpr(sprUrl: string) {
        let spr = await ResManager1.ins.loadRes(sprUrl, cc.SpriteFrame, BUNDLE_TYPE_ENUM.LEVEL);
        Tools.setSpriteFrame(this.node, spr);
    }
    /** 获取一个其他回调方法的Tween */
    getOtherCallTween(info: TweenInfo) {
        switch (info.type) {
            case "talk_1":    //说话
                return this.showTalk(info);
            case "talk_2":    //说话
                return this.showTalk(info, 2);
            case "talk_3":
                return this.showTalk(info, 3);
            case "talk_4":
                return this.showTalk(info, 4);
            case "talk_4_scale":
                return this.showTalk(info, 4,);
            case "audio":    //播放声音
                return this.playAudio(info.value);
            case "stop":     //结束某个Tween
                return this.stopTween(info.value);
            case "stopBg":     //停止背景音乐
                return AudioManager1.stopBG();
            case "stopAudio":     //根据名字结束某个音频
                return AudioManager1.stopAudioForName(info.value);
            case "stopAllAudio":     //结束所有音频
                return AudioManager1.stopAllAudio();
            case "over":     //游戏结束
                var isWinReGameBtnBendi = Tools.getStorage('isWinReGameBtn')
                if (isWinReGameBtnBendi) {
                    AudioManager1.playAudio("shibai", 1, BUNDLE_TYPE_ENUM.GAME);
                    setTimeout(() => {
                        let animTime = UIManager.ins.closeAll();
                        setTimeout(() => LevelManager.ins.loadLevelPre(), animTime * 1000)
                    }, 2000);
                }
                if (this.levelBase.getIsAgain() && isWinReGameBtnBendi == null) {
                    EventManager.ins.emit(EVENT_NAME_ENUM.PAUSE_TIME);
                    return UIManager.ins.showPop("ReviveUI", BUNDLE_TYPE_ENUM.GAME, info.value);
                }
                EventManager.ins.emit(EVENT_NAME_ENUM.STOP_TIME);
                return UIManager.ins.showPop("OverUI", BUNDLE_TYPE_ENUM.GAME, info.value);
            case "win":      //游戏胜利
            case "openWin":   //打开胜利页面
                var isWinReGameBtnBendi = Tools.getStorage('isWinReGameBtn')
                if (isWinReGameBtnBendi) {
                    AudioManager1.playAudio("chenggong", 1, BUNDLE_TYPE_ENUM.GAME);
                    setTimeout(() => {
                        let animTime = UIManager.ins.closeAll();
                        setTimeout(() => LevelManager.ins.loadLevelPre(), animTime * 1000)
                    }, 2000);
                }
                EventManager.ins.emit(EVENT_NAME_ENUM.STOP_TIME);
                return UIManager.ins.showPop("WinUI", BUNDLE_TYPE_ENUM.GAME, info.value);
            case "finish":   //抛出完成当前Tween事件
                return EventManager.ins.emit(EVENT_NAME_ENUM.FINISH_INTER_TWEEN, info.value, this);
            case "otherTween":   //执行其他交互Tween事件
                return EventManager.ins.emit(EVENT_NAME_ENUM.RUN_NODE_TWEEN, info.node, info.value);
            case "switchBgm":  //切换背景音乐  音量
                return this.levelBase.switchBgm(info.value.resUrl, info.value.value, info.time);
            case "armatureScale":
                return this.setArmtureScale(info.time, info.timeScale);
            case "CountEn":   // 累加计数,执行_指定Tween事件  每需要计算一个事件，就需要创建一个空节点,并将node值填入该空节点名字。
                return this.CountEnFun(info.node, info.value, info.time, info.timeScale);

        }
        return null;
    };
    /** 判断两个节点是否相交 */
    isNodeInterNode(node1: cc.Node, node2: cc.Node) {
        if (!node1.active || !node2.active) { return false; };
        let wordPos1 = Tools.getToWorldPosAR(node1);
        let worldScale1 = this.getWorldScale2(node1.scale, node1);
        let wordPos2 = Tools.getToWorldPosAR(node2);
        let worldScale2 = this.getWorldScale2(node2.scale, node2);
        let size1 = cc.size(node1.width * worldScale1, node1.height * worldScale1);
        let size2 = cc.size(node2.width * worldScale2, node2.height * worldScale2);

        let rect1 = new cc.Rect(wordPos1.x - size1.width / 2, wordPos1.y - size1.height / 2, size1.width, size1.height);
        let rect2 = new cc.Rect(wordPos2.x - size2.width / 2, wordPos2.y - size2.height / 2, size2.width, size2.height);
        if (cc.Intersection.rectRect(rect1, rect2)) {
            return true;
        }
        return false;
    };
    /** 获取世界Scale */
    getWorldScale(tempScale: number = 1, node: cc.Node) {
        if (node.parent) {
            return this.getWorldScale(tempScale / node.parent.scale, node.parent);
        }
        return tempScale;
    };
    /** 获取世界Scale */
    getWorldScale2(tempScale: number = 1, node: cc.Node) {
        if (node.parent) {
            return this.getWorldScale2(tempScale * node.parent.scale, node.parent);
        }
        return tempScale;
    };
}
